"""
Blueprint 扩展模块

虽然 Blueprint 本身是 Flask 框架的核心特性而不是第三方扩展，
但将所有路由的注册统一放在一个扩展模块中初始化有以下好处：

1. 统一路由管理：所有 Blueprint 在一个地方注册，便于查看和管理
2. 依赖管理：确保在注册路由前，所有依赖项已经正确初始化
3. 统一 CORS 配置：在这里可以统一为所有 Blueprint 配置跨域策略
4. 模块化解耦：将路由注册与应用创建逻辑分离，提高代码可维护性
"""

from configs import dify_config
from dify_app import DifyApp


def init_app(app: DifyApp):
    """
    初始化应用的蓝图路由

    该函数负责注册所有蓝图(Blueprint)并配置相应的跨域资源共享(CORS)策略。
    每个蓝图代表应用的一个功能模块，具有不同的用途和访问策略。

    Dify应用根据不同使用场景划分了多个功能模块：
    1. Service API - 为应用提供后端服务API，供外部应用调用
    2. Web API - 为Web前端提供API接口
    3. Console API - 为管理控制台提供API接口
    4. Files API - 专门处理文件上传下载等操作
    5. Inner API - 处理系统内部通信

    :param app: DifyApp实例，需要注册蓝图的Flask应用实例
    :return: None
    """
    # register blueprint routers and configure CORS policies

    from flask_cors import CORS  # type: ignore

    from controllers.console import bp as console_app_bp
    from controllers.files import bp as files_bp
    from controllers.inner_api import bp as inner_api_bp
    from controllers.service_api import bp as service_api_bp
    from controllers.web import bp as web_bp

    # 配置并注册服务API蓝图
    # 服务API是供外部应用程序调用的接口，主要用于应用集成场景
    # 允许Content-Type, Authorization, X-App-Code请求头，支持所有常见HTTP方法
    CORS(
        service_api_bp,
        # 允许的请求头：
        # Content-Type: 指定请求体的媒体类型
        # Authorization: 包含认证信息的请求头
        # X-App-Code: Dify应用标识码，用于识别调用方应用
        allow_headers=["Content-Type", "Authorization", "X-App-Code"],
        # 允许的HTTP方法：
        # GET: 获取资源
        # PUT: 更新资源
        # POST: 创建资源
        # DELETE: 删除资源
        # OPTIONS: 预检请求，用于CORS检查
        # PATCH: 部分更新资源
        methods=["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"],
    )
    app.register_blueprint(service_api_bp)

    # 配置并注册Web API蓝图
    # Web API主要处理前端Web应用的请求，支持凭证和更详细的跨域配置
    # 根据配置允许指定的来源访问，支持携带认证信息(credentials)
    # 允许Content-Type, Authorization, X-App-Code请求头
    # 暴露X-Version和X-Env响应头给前端应用使用
    CORS(
        web_bp,
        # 资源配置，对所有路径应用以下规则：
        resources={
            r"/*": {
                # 允许访问的来源，从配置中读取WEB_API_CORS_ALLOW_ORIGINS
                # 可以是单个来源如"http://localhost:3000"或通配符"*"
                "origins": dify_config.WEB_API_CORS_ALLOW_ORIGINS
            }
        },
        # 支持携带认证信息（cookies、authorization headers等）
        # 当设置为True时，浏览器会在跨域请求中包含凭证信息
        supports_credentials=True,
        # 允许的请求头：
        # Content-Type: 指定请求体的媒体类型
        # Authorization: 包含认证信息的请求头
        # X-App-Code: Dify应用标识码
        allow_headers=["Content-Type", "Authorization", "X-App-Code"],
        # 允许的HTTP方法：
        # GET: 获取资源
        # PUT: 更新资源
        # POST: 创建资源
        # DELETE: 删除资源
        # OPTIONS: 预检请求，用于CORS检查
        # PATCH: 部分更新资源
        methods=["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"],
        # 暴露给浏览器的响应头：
        # X-Version: 应用版本信息
        # X-Env: 应用运行环境信息（如production、development）
        expose_headers=["X-Version", "X-Env"],
    )

    app.register_blueprint(web_bp)

    # 配置并注册控制台应用蓝图
    # 控制台应用主要处理管理后台的请求，具有独立的跨域配置
    # 根据CONSOLE_CORS_ALLOW_ORIGINS配置允许指定来源访问，支持携带认证信息
    # 允许Content-Type和Authorization请求头
    # 暴露X-Version和X-Env响应头给控制台应用使用
    CORS(
        console_app_bp,
        # 资源配置，对所有路径应用以下规则：
        resources={
            r"/*": {
                # 允许访问的来源，从配置中读取CONSOLE_CORS_ALLOW_ORIGINS
                # 通常是管理后台的前端地址
                "origins": dify_config.CONSOLE_CORS_ALLOW_ORIGINS
            }
        },
        # 支持携带认证信息（cookies、authorization headers等）
        # 管理后台通常需要用户登录状态，因此需要支持凭证
        supports_credentials=True,
        # 允许的请求头：
        # Content-Type: 指定请求体的媒体类型
        # Authorization: 包含认证信息的请求头
        allow_headers=["Content-Type", "Authorization"],
        # 允许的HTTP方法：
        # GET: 获取资源
        # PUT: 更新资源
        # POST: 创建资源
        # DELETE: 删除资源
        # OPTIONS: 预检请求，用于CORS检查
        # PATCH: 部分更新资源
        methods=["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"],
        # 暴露给浏览器的响应头：
        # X-Version: 应用版本信息
        # X-Env: 应用运行环境信息（如production、development）
        expose_headers=["X-Version", "X-Env"],
    )

    app.register_blueprint(console_app_bp)

    # 配置并注册文件处理蓝图
    # 文件蓝图专门处理文件上传、下载等操作
    # 仅允许Content-Type请求头，支持所有常见HTTP方法
    CORS(
        files_bp,
        # 允许的请求头：
        # Content-Type: 指定请求体的媒体类型，文件操作必须
        allow_headers=["Content-Type"],
        # 允许的HTTP方法：
        # GET: 下载文件
        # PUT: 更新文件
        # POST: 上传文件
        # DELETE: 删除文件
        # OPTIONS: 预检请求，用于CORS检查
        # PATCH: 部分更新文件
        methods=["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"]
    )
    app.register_blueprint(files_bp)

    # 注册内部API蓝图
    # 内部API用于系统内部通信，不需要跨域配置
    # 通常用于插件系统和工作空间相关的内部操作
    app.register_blueprint(inner_api_bp)